//
//  LogUtil.swift
//  SYGovernment
//
//  Created by 思域 on 2020/9/25.
//  Copyright © 2020 思域. All rights reserved.
//

import Foundation

private var logEnabledKey = "logEnabledKey"

/// 缓存
private var logCache = [String: String]()

public extension UIViewController {

    /// 日志显示
    var logEnabled: Bool {
        set {
            objc_setAssociatedObject(self, &logEnabledKey, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
        }
        get {
            return (objc_getAssociatedObject(self, &logEnabledKey) as? Bool) ?? false
        }
    }

    override func motionEnded(_ motion: UIEvent.EventSubtype, with event: UIEvent?) {
        if logEnabled == false {
            return
        }
        guard let window = UIApplication.shared.keyWindow else {
            return
        }
        let logView = _LogView.shared
        if window.subviews.contains(logView) {
            return
        }
        window.endEditing(true)
        window.addSubview(logView)
        logView.reloadData()
        UIView.animate(withDuration: 0.25) {
            logView.y = 0
        }
    }

    override var canBecomeFirstResponder: Bool {
        true
    }
}

/**
 日志收集工具
 在打印的地方收集日志，---->  LogUtil.addLog("日志")
 controller.logEnabled 可开启日志展示
 再摇一摇触发
 */
public class LogUtil: NSObject {
    /// 添加log
    public static func addLog(_ log: String) {
        logs.append(StringObj(string: log))
    }

    /// 存放所有log
    private static var logs = [StringObj]()

    /// 获取所有log
    fileprivate static func getLogs() -> [StringObj] {
        return logs
    }

    /// 清除log
    fileprivate static func removeAll() {
        logs.removeAll()
    }

}

fileprivate class StringObj: NSObject {
    var height: CGFloat = 0
    var str: String = ""
    var key: String?
    init(string: String) {
        if string.count > 1000 {
            str = (string as NSString).substring(to: 1000)
            let key = "\(Int(Date().timeIntervalSince1970) + Int(arc4random()))".md5()
            self.key = key
            logCache[key] = string
        } else {
            str = string
        }
        super.init()
    }
}

fileprivate class _LogView: UIView, UITableViewDelegate, UITableViewDataSource {

    static let shared: _LogView = _LogView(frame: CGRect(x: 0, y: kScreenH, width: kScreenW, height: kScreenH))

    private var tableView: UITableView!
    private var logs = [StringObj]()
    private var cover: UIView!
    private var current: IndexPath?

    override init(frame: CGRect) {
        super.init(frame: frame)
        backgroundColor = UIColor.red
        let title = UILabel.withText("日志输出", fontSize: 17, color: .white, frame: CGRect(x: 0, y: kStatusBarH, width: kScreenW, height: 44))
        title.textAlignment = .center
        addSubview(title)

        let close = UIButton.withTitle("关闭", titleColor: .white, backgroundColor: nil, fontSize: 15, image: nil, frame: CGRect(x: 0, y: kStatusBarH, width: 80, height: 44))
        addSubview(close)
        close.addTarget(self, action: #selector(_close), for: .touchUpInside)

        let clear = UIButton.withTitle("清空", titleColor: .white, backgroundColor: nil, fontSize: 15, image: nil, frame: CGRect(x: kScreenW - 80, y: kStatusBarH, width: 80, height: 44))
        addSubview(clear)
        clear.addTarget(self, action: #selector(_clear), for: .touchUpInside)

        let tableView = UITableView(frame: CGRect(x: 0, y: kSafeTopH, width: kScreenW, height: kScreenH - kSafeBottomH - kSafeTopH), style: .plain)
        tableView.delegate = self;
        tableView.dataSource = self;
        tableView.backgroundColor = .clear
        tableView.separatorStyle = .singleLine;
        tableView.tableFooterView = UIView()
        tableView.register(_LogCell.self, forCellReuseIdentifier: "ID")
        addSubview(tableView)
        self.tableView = tableView;
    }

    required init?(coder: NSCoder) {
        nil
    }

    @objc private func _close() {
        UIView.animate(withDuration: 0.25, animations: {
            self.y = kScreenH
        }) { (b) in
            self.removeFromSuperview()
        }
    }

    @objc private func _clear() {
        UIView.animate(withDuration: 0.25, animations: {
            self.y = kScreenH
        }) { (b) in
            self.removeFromSuperview()
            LogUtil.removeAll()
        }
    }

    override var canBecomeFirstResponder: Bool {
        true
    }


    func reloadData() {

        let arr = LogUtil.getLogs()
        for log in arr {
            if log.height == 0 {
                fomatteCalculateHeight(log)
            }
        }
        self.logs = arr
        tableView.reloadData()

    }

    private func fomatteCalculateHeight(_ log: StringObj) {
        var newStr = log.str
        while newStr.hasSuffix("\n") {
            newStr.removeLast()
        }

        let nsstr = newStr as NSString
        let key: NSAttributedString.Key = .font
        let h = nsstr.boundingRect(with: CGSize(width: kScreenW - 20, height: 10000), options: .usesLineFragmentOrigin, attributes: [key: UIFont.systemFont(ofSize: 12)], context: nil).height + 10
        log.height = min(h < 44 ? 44 : h, _maxHeight)
        log.str = newStr
    }

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        logs.count
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "ID") as! _LogCell
        cell.content = logs[indexPath.row].str
        return cell
    }

    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        logs[indexPath.row].height
    }

    func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
        200
    }

    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        let log = logs[indexPath.row]
        current = indexPath
        if self.cover != nil {
            let textView = cover.subviews.first as! UITextView
            let txt: String
            if let key = log.key, let _txt = logCache[key] {
                txt = _txt
            } else {
                txt = log.str
            }
            textView.text = txt
            cover.isHidden = false
            textView.contentOffset = CGPoint.zero
            return
        }
        let cover = UIView.with(UIColor.black.withAlphaComponent(0.5), frame: self.tableView.frame)
        self.cover = cover

        let textView = UITextView(frame: CGRect(x: 10, y: 10, width: cover.width - 20, height: cover.height - 65 - kSafeBottomH))
        textView.isEditable = false
        textView.isSelectable = false
        textView.font = UIFont.systemFont(ofSize: 14)
        textView.backgroundColor = .white
        textView.text = log.str
        cover.addSubview(textView)

        let btn = UIButton.withTitle("copy", titleColor: .white, backgroundColor: .red, fontSize: 18, image: nil, frame: CGRect(x: 10, y: textView.maxY, width: textView.width, height: 45))

        let cor: UIRectCorner = [.bottomLeft, .bottomRight]
        btn.setCornerRadius(12, rounding: cor)
        cover.addSubview(btn)
        btn.addTarget(self, action: #selector(_copy(_:)), for: .touchUpInside)

        textView.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(_tap)))
        addSubview(cover)
    }

    @objc private func _copy(_ btn: UIButton) {
        if let t = btn.superview?.subviews.first as? UITextView {
            UIPasteboard.general.string = t.text
            cover.isHidden = true
            self.tableView.deselectRow(at: current!, animated: true)
        }
    }

    @objc private func _tap() {
        cover.isHidden = true
        self.tableView.deselectRow(at: current!, animated: true)
    }

}

fileprivate let _maxHeight: CGFloat = 200;

fileprivate class _LogCell: UITableViewCell {
    var content: String = "" {
        didSet {
            _text.text = content
            _text.frame = CGRect(x: 10, y: 5, width: kScreenW - 20, height: 200)
            _text.sizeToFit()
            if _text.height > _maxHeight {
                _text.height = _maxHeight
            }
        }
    }
    var _text: UILabel!

    override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
        super.init(style: style, reuseIdentifier: reuseIdentifier)

        _text = UILabel.withText(nil, fontSize: 12, color: .black, frame: CGRect.zero)
        _text.numberOfLines = 0
        _text.preferredMaxLayoutWidth = kScreenW - 20
        contentView.addSubview(_text)
    }

    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}


